﻿using BLL;
using IBLL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Tools;
using webMvc.Models.Jurisdiction;

namespace webMvc.Authorization
{
	public class MyAuthentication : AuthorizeAttribute
	{
		IUserInfoService userInfosService = new UserInfoService();
		IRoleInfoService roleInfoService = new RoleInfoService();
		IRoleActionMapperService roleActionMapperService = new RoleActionMapperService();
		IUserRoleMapperService userRoleMapperService = new UserRoleMapperService();
		IActionInfoService actionInfoService = new ActionInfoService();
		public AuthorizeType authorizeType { get; set; }

		public enum AuthorizeType
		{
			noLogin = -1,
			noJurisdiction = -2,
			isojbk = 1
		}

		/// <summary>
		/// 检查是否授权成功
		/// </summary>
		/// <param name="httpContext"></param>
		/// <returns></returns>
		protected override bool AuthorizeCore(HttpContextBase httpContext)
		{
			var SessionIsOk = false;

			//如果有token则进行用户权限判定

			string Token = "";
			string RequestController = httpContext.Request.RequestContext.RouteData.Values["controller"].ToString().ToLower();
			string RequestAction = httpContext.Request.RequestContext.RouteData.Values["action"].ToString().ToLower();
			string Method = httpContext.Request.HttpMethod.ToLower();
			int uid = -1;
			if (httpContext.Session["token"] != null)
			{
				ServiceUserToken serviceUserToken = httpContext.Session["token"] as ServiceUserToken;
				if (serviceUserToken != null)
				{
					uid = serviceUserToken.uid;
					Token = serviceUserToken.Token;
					SessionIsOk = true;
				}
			}
			//从请求的token进行验证,或者从cookie中进行验证
			else if (httpContext.Request["token"] != null)
			{
				string ClientToken = httpContext.Request["token"].ToString();

				SessionIsOk = getTokenIsOk(Token, ClientToken, httpContext, out uid);
				#region 未封装之前
				//if (Token == ClientToken)
				//{
				//	SessionIsOk = true;
				//}
				//else
				//{
				//	TypeDesToken typeDesToken = new TypeDesToken();
				//	//解析一下传入的token,如果可以重新进行session的赋值
				//	string jiemi = typeDesToken.FoXiGetToken(ClientToken);
				//	string[] uNameAndPwd = jiemi.Split('|');
				//	if (uNameAndPwd != null && uNameAndPwd.Length == 2)
				//	{
				//		var getLoginModel = userInfosService.LoadEntities(x => x.Uname == uNameAndPwd[0] && x.Upwd == uNameAndPwd[1]).FirstOrDefault();
				//		if (getLoginModel != null)
				//		{
				//			Token = typeDesToken.FoXiMakeToken(getLoginModel.Uname, getLoginModel.Upwd);
				//			httpContext.Session["Token"] = new ServiceUserToken() { uid = getLoginModel.Id, Token = Token };
				//		}
				//	}
				//}
				#endregion

			}
			else if (httpContext.Request.Cookies["token"] != null)
			{
				string ClientToken = httpContext.Request.Cookies["token"].ToString();
				SessionIsOk = getTokenIsOk(Token, ClientToken, httpContext, out uid);
			}

			//权限校验
			if (SessionIsOk && uid != -1)
			{
				authorizeType = AuthorizeType.noJurisdiction;
				var userRoleMapper = userRoleMapperService.LoadEntities(x => x.Userid == uid).FirstOrDefault();
				SessionIsOk = false;

				if (userRoleMapper != null)
				{
					var roleInfoIsOk = roleInfoService.LoadEntities(x => x.DelFlag == false && x.Id == userRoleMapper.Roleid).FirstOrDefault();

					if (roleInfoIsOk != null)
					{
						int[] actionArray = roleActionMapperService.LoadEntities(x => x.RoleId == roleInfoIsOk.Id).Select(x => x.AactionId).ToArray();
						if (actionArray != null && actionArray.Length > 0)
						{
							var actionList = actionInfoService.LoadEntities(x => actionArray.Contains(x.Id)).Select(x => new
							{
								ParRequestController = x.ControllerName.ToLower(),
								ParRequestAction = x.ActionInfoName.ToLower(),
								ParMethod = x.ActionMethodName.ToLower()
							}).ToArray();

							if (actionList != null && actionList.Length > 0)
							{
								var getCount = actionList.Where(x => x.ParMethod == Method && x.ParRequestAction == RequestAction && x.ParRequestController == RequestController).Count();

								SessionIsOk = getCount > 0;

								//SessionIsOk = actionList.Contains(new
								//{
								//	RequestController = RequestController.ToLower(),
								//	RequestAction = RequestAction.ToLower(),
								//	Method = Method.ToLower()
								//});
								if (SessionIsOk)
								{
									authorizeType = AuthorizeType.isojbk;
								}
							}
						}
					}
				}
			}
			else
			{
				authorizeType = AuthorizeType.noLogin;
			}
			return SessionIsOk;
		}

		public bool getTokenIsOk(string Token, string ClientToken, HttpContextBase httpContext, out int id)
		{
			bool SessionIsOk = false;
			id = -1;
			if (Token == ClientToken)
			{
				SessionIsOk = true;
			}
			else
			{
				TypeDesToken typeDesToken = new TypeDesToken();
				//解析一下传入的token,如果可以重新进行session的赋值
				string jiemi = typeDesToken.FoXiGetToken(ClientToken);
				string[] uNameAndPwd = jiemi.Split('|');
				if (uNameAndPwd != null && uNameAndPwd.Length == 2)
				{
					string buffUname = uNameAndPwd[0];
					string buffUpwd = uNameAndPwd[1];
					var getLoginModel = userInfosService.LoadEntities(x => x.Uname == buffUname && x.Upwd == buffUpwd).FirstOrDefault();
					if (getLoginModel != null)
					{
						id = getLoginModel.Id;
						Token = typeDesToken.FoXiMakeToken(getLoginModel.Uname, getLoginModel.Upwd);
						httpContext.Session["Token"] = new ServiceUserToken() { uid = getLoginModel.Id, Token = Token };
						SessionIsOk = true;
					}
				}
			}
			return SessionIsOk;
		}


		/// <summary>
		/// 授权失败方法
		/// </summary>
		/// <param name="filterContext"></param>
		protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
		{
			switch (authorizeType)
			{
				case AuthorizeType.noLogin:
					filterContext.HttpContext.Response.Redirect("/test/login");
					break;
				case AuthorizeType.noJurisdiction:
					filterContext.HttpContext.Response.Redirect("/test/NoAuthority");
					break;
			}
			//base.HandleUnauthorizedRequest(filterContext);
		}
	}
}